package com.ruoyi.common.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

public class FileUtil {

    private static final String SERVER_URL = "http://cloud.sd.clic:8087/files/fileserve/danganfile/savefile";

    /**
     * 以流的方式 发送文件和json对象,保存
     * multipartFile文件
     *
     * @return
     */
    public static R<String> doPostFileStreamAndJsonObj(MultipartFile multipartFile, SysUser resaveUser) throws IOException {
        JSONObject json = new JSONObject();

        json.put("token", "b95a47f5-8b8c-3373-c93d-2d6b237bd4e4");
        json.put("sys", "dangan");
        json.put("uid", resaveUser.getUserName());
        json.put("fn", resaveUser.getNickName());

        String dbpath = "dangan" + File.separator + DateUtil.formatDate(new Date()) + File.separator + multipartFile.getOriginalFilename();
        if (dbpath.contains("\\")) {
            dbpath = dbpath.replace("\\", "/");
        }
        json.put("savepath", dbpath);
        json.put("fliename", multipartFile.getName());
        json.put("mail", resaveUser.getEmail());


        HttpUtil.createPost(SERVER_URL)
                .form("file", multipartFile.getBytes(), multipartFile.getName())
                .form(json)
                .execute();

        String result = "";// 请求返回参数
        try {
            String jsonString = json.toString();
            // 开始设置模拟请求的参数，额，不一个个介绍了，根据需要拿
            String boundary = "------WebKitFormBoundaryUey8ljRiiZqhZHBu";
            URL u = new URL(SERVER_URL);
            HttpURLConnection conn = (HttpURLConnection) u.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("connection", "Keep-Alive");
            // 这里模拟的是火狐浏览器，具体的可以f12看看请求的user-agent是什么
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Charsert", "UTF-8");
            // 这里的content-type要设置成表单格式，模拟ajax的表单请求
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            conn.setRequestProperty("Cloud-Type", "dangan1943");
            // 指定流的大小，当内容达到这个值的时候就把流输出
            conn.setChunkedStreamingMode(10240000);

            // 定义输出流，有什么数据要发送的，直接后面append就可以，记得转成byte再append
            OutputStream out = new DataOutputStream(conn.getOutputStream());
            byte[] end_data = ("\r\n--" + boundary + "--\r\n").getBytes();// 定义最后数据分隔线

            StringBuilder sb = new StringBuilder();
            // 添加form属性
            sb.append("--");
            sb.append(boundary);
            sb.append("\r\n");
            // 这里存放要传输的参数，name = xml
            sb.append("Content-Disposition: form-data; name=\"JsonObj\"");
            sb.append("\r\n\r\n");
            // 把要传的json字符串放进来
            sb.append(jsonString);
            out.write(sb.toString().getBytes("utf-8"));
            out.write("\r\n".getBytes("utf-8"));

            sb = new StringBuilder();
            sb.append("--");
            sb.append(boundary);
            sb.append("\r\n");
            // 这里的参数啥的是我项目里对方接收要用到的，具体的看你的项目怎样的格式
            String feifan = json.getStr("fliename");
            sb.append("Content-Disposition: form-data;name=\"File"
                    + "\";filename=\"" + feifan + "\"\r\n");
            // 这里拼接个fileName，方便后面用第一种方式接收（如果是纯文件，不带其他参数，就可以不用这个了，因为Multipart可以直接解析文件）
//			sb.append("FileName:" + file.getName() + "\r\n");
            // 发送文件是以流的方式发送，所以这里的content-type是octet-stream流
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            byte[] data = sb.toString().getBytes("utf-8");
            out.write(data);
            byte[] byteArr = multipartFile.getBytes();
            InputStream in = new ByteArrayInputStream(byteArr);

            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
            in.close();
            // 发送流
            out.write(end_data);
            out.flush();
            out.close();
            // 定义BufferedReader输入流来读取URL的响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = "";
            while ((line = reader.readLine()) != null) {
                result += line;
            }
            // 后面可以对结果进行解析（如果返回的是格式化的数据的话）
            return R.ok(result);
        } catch (Exception e) {
            System.out.println("发送POST请求出现异常！" + e);
            e.printStackTrace();
            return R.fail(e.toString());
        }
    }

    public R<String> delfile(String url, String sys, String token, String path, String uid, String fn) throws Exception {
        JSONObject data = new JSONObject();
        data.put("token", token);
        data.put("sys", sys);
        data.put("path", path);
        data.put("uid", uid);
        data.put("fn", fn);
        JSONObject out = post(url, data.toString());
        if (out.getStr("result").equals("1")) {
            return R.ok(JSONUtil.toJsonStr(out));
        } else {
            return R.fail(JSONUtil.toJsonStr(out));
        }
    }

    public R<String> zipfile(String url, String sys, String token, String uid, String fn, String zippath, String savepath) throws Exception {
        JSONObject data = new JSONObject();
        data.put("sys", sys);
        data.put("token", token);
        data.put("uid", uid);
        data.put("fn", fn);
        data.put("zippath", zippath);
        data.put("savepath", savepath);
        JSONObject out = post(url, data.toString());
        System.out.println("获取zipfile" + out);
        if (out.getStr("result").equals("1")) {
            return R.ok();
        } else {
            return R.fail("获取token失败！" + out);
        }
    }

    /**
     * @param url
     * @param param
     * @return
     */
    public JSONObject post(String url, String param) throws Exception {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder sb = null;
        {
            sb = new StringBuilder();
            try {
                URL realUrl = new URL(url);

                URLConnection conn = null;
                conn = realUrl.openConnection();
                // if (proxy == null) {
                // conn = realUrl.openConnection();
                // } else {
                // conn = realUrl.openConnection(proxy);
                // }

                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                conn.setRequestProperty("Content-type", "application/json");
                // conn.setRequestProperty("Authorization", "Bearer " +
                // accessToken);
                conn.setDoOutput(true);
                conn.setDoInput(true);
                out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
                out.print(param);
                out.flush();
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                }
            } catch (Throwable e) {
                e.printStackTrace();
                System.out.println("发送请求出现异常！" + e.getMessage());
            } finally {
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
        try {
            return JSONUtil.parseObj(sb.toString());
        } catch (Throwable e) {
            e.printStackTrace();
            // return null;
            throw e;
            // TODO: handle exception
        }
    }


}
